package com.rongji.dfish.misc.util;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;

/**
 * XML工具类(临时),使用此工具类需要导入dom4j.jar,
 * FIXME 这里的方法可能要与XMLTools类合并
 * 
 * @author DFish Team
 * 
 */
public class XMLUtil {

    private Document document = null;

    public Document getDocument() {
        return document;
    }

    public void setDocument(Document document) {
        this.document = document;
    }

    public XMLUtil() {
        document = DocumentHelper.createDocument();
    }

    public XMLUtil(Document document) {
        this.document = document;
    }

    public XMLUtil(InputStream inputStream) throws DocumentException {
        document = new SAXReader().read(inputStream);
    }

    public XMLUtil(File file) throws DocumentException {
        document = new SAXReader().read(file);
    }

    public XMLUtil(String fileName) throws DocumentException {
        document = new SAXReader().read(new File(fileName));
    }

    /**
     * 是否有子节点
     * 
     * @param parentTextName
     *            父节点名称
     * @return 是否有子节点
     */
    public boolean hasChildElement(String parentTextName) {
        return false;
    }

    /**
     * 获取根节点下的所有子节点
     * 
     * @return 根节点下的所有子节点列表
     */
    public List<Element> getTopElements() {
        return getChildElements(document.getRootElement());
    }

    /**
     * 获取根节点下的所有子节点名称
     * 
     * @return
     */
    public List<String> getTopElementNames() {
        return getChildElementNames(document.getRootElement());
    }

    /**
     * 根据父节点获取其所有子节点
     * 
     * @param element
     *            父节点
     * @return 所有子节点列表
     */
    @SuppressWarnings("unchecked")
    public List<Element> getChildElements(Element element) {
        List<Element> dataList = new ArrayList<Element>();
        List<Element> childList = element.elements();
        if (childList != null) {
            for (Element child : childList) {
                dataList.add(child);
            }
        }
        return dataList;
    }

    /**
     * 根据父节点获取其子节点名称
     * 
     * @param element
     *            父节点
     * @return 所有子节点名称列表
     */
    @SuppressWarnings("unchecked")
    public List<String> getChildElementNames(Element element) {
        List<String> dataList = new ArrayList<String>();
        List<Element> childList = element.elements();
        if (childList != null) {
            for (Element child : childList) {
                dataList.add(child.getName());
            }
        }
        return dataList;
    }

    /**
     * 根据父节点获取其子节点值
     * 
     * @param element
     *            父节点
     * @return 子节点值的列表
     */
    @SuppressWarnings("unchecked")
    public List<String> getChildElementValues(Element element) {
        List<String> dataList = new ArrayList<String>();
        List<Element> childList = element.elements();
        if (childList != null) {
            for (Element child : childList) {
                dataList.add(child.getStringValue());
            }
        }
        return dataList;
    }

    /**
     * 创建文档实例
     * 
     * @param dataMap
     *            数据集合(key对应的是根结点下的子结点(类结点),value对应的此结点下的所有数据)
     * @param rootName
     *            根结点的名称
     * @param singleObjName
     *            (单个对象结点的名称)
     * @return 创建好的文档实例
     */
    public Document createDocument(Map<String, List<String[]>> dataMap, String rootName, String singleObjName) {
        Element rootElement = document.getRootElement();
        if (dataMap != null) {
            for (Entry<String, List<String[]>> entry : dataMap.entrySet()) {
                if (rootElement == null) {
                    rootElement = document.addElement(rootName);
                }
                List<String[]> dataList = entry.getValue();
                String cateName = entry.getKey();
                if (dataList != null && dataList.size() > 1) {
                    String[] nodeNames = dataList.get(0);
                    Element cate = rootElement.addElement(cateName);
                    for (int i = 1; i < dataList.size(); i++) {
                        Element singleElement = cate.addElement(singleObjName);
                        String[] data = dataList.get(i);
                        for (int j = 0; j < data.length; j++) {
                            Element node = singleElement.addElement(nodeNames[j]);
                            String text = data[j];
                            text = (text == null) ? "" : text;
                            node.setText(text);
                        }
                    }
                }
            }
        }
        return document;
    }

    /**
     * 创建文档实例,默认根结点的名称为"root"
     * 
     * @param dataMap
     *            数据集合(key对应的是根结点下的子结点(类结点),value对应的此结点下的所有数据)
     * @param singleObjName
     *            (单个对象结点的名称)
     * @return 创建好的文档实例
     */
    public Document createDocument(Map<String, List<String[]>> dataMap, String singleObjName) {
        return createDocument(dataMap, "root", singleObjName);
    }

    /**
     * 获取XML的格式,以换行、易看懂的格式
     * 
     * @return 设置好的XML格式
     */
    public OutputFormat getFormat() {
        OutputFormat format = OutputFormat.createPrettyPrint();
        format.setEncoding("UTF-8");
        format.setIndent("\t");
        return format;
    }

    /**
     * 将XML文档以输出流的形式输出
     * 
     * @param outputStream
     *            输出流
     * @param document
     *            XML的文档
     * @return 是否输出成功,true表示成功,false表示失败
     */
    public boolean write(OutputStream outputStream, Document document) {
        XMLWriter writer = null;
        boolean isSuccess = true;
        try {
            writer = new XMLWriter(outputStream, getFormat());
            writer.write(document);
        } catch (Exception e) {
            isSuccess = false;
        } finally {
            if (writer != null) {
                try {
                    writer.close();
                } catch (IOException e) {
                    isSuccess = false;
                }
            }
        }
        return isSuccess;
    }
}
